package com.jnc.core.config.shiro.session;

import com.jnc.common.constant.ShiroConstant;
import com.jnc.common.util.convert.SerializeUtil;
import com.jnc.core.config.redis.RedisStore;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;

import java.io.Serializable;
import java.util.Collection;

/**
 * @Author: jjn
 * @Date: 2018/10/15
 * @Desc:
 */
@Slf4j
public class RedisShiroSessionDAO extends EnterpriseCacheSessionDAO {

    private RedisStore redisStore;

    public RedisShiroSessionDAO(RedisStore redisStore) {
        this.redisStore = redisStore;
    }

    /**
     * 创建session
     * 如DefaultSessionManager在创建完session后会调用该方法；
     * 如保存到关系数据库/文件系统/NoSQL数据库；即可以实现会话的持久化；
     * 返回会话ID；主要此处返回的ID.equals(session.getId())
     * @param session
     * @return
     */
    @Override
    protected Serializable doCreate(Session session) {
        log.debug("begin doCreate sessionId: {}", session.getId());
        if(null == session){
            return null;
        }
        Serializable sessionId = super.doCreate(session);
        final byte[] key = getSessionKey(sessionId.toString());
        //把session信息存储到redis中
        redisStore.setExpire(key, SerializeUtil.serialize(session), ShiroConstant.EXPIRE_SECONDS);
        return sessionId;
    }

    /**
     * 根据会话ID获取会话
     * @param sessionId
     * @return
     */
    @Override
    protected Session doReadSession(Serializable sessionId) {
        log.debug("begin doReadSession sessionId: {}", sessionId);
        if(null == sessionId){
            return null;
        }
        byte[] key = getSessionKey(sessionId.toString());
        byte[] value = redisStore.get(key);
        Session session = (Session) SerializeUtil.deserialize(value);
        return session;
    }

    /**
     * 更新会话；如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用
     * @param session
     */
    @Override
    protected void doUpdate(Session session) {
        log.debug("begin doUpdate sessionId: {}", session.getId());
        if(session == null || session.getId() == null){
            return;
        }
        byte[] key = getSessionKey(session.getId().toString());
        //把session信息存储到redis中
        redisStore.setExpire(key, SerializeUtil.serialize(session), ShiroConstant.EXPIRE_SECONDS);
    }

    /**
     * 删除会话；当会话过期/会话停止（如用户退出时）会调用
     * @param session
     */
    @Override
    protected void doDelete(Session session) {
        log.debug("begin doDelete sessionId: {}", session.getId());
        if(session == null || session.getId() == null){
            return;
        }
        byte[] key = getSessionKey(session.getId().toString());
        //从redis中删除ression
        redisStore.del(key);
    }

    /**
     * 获取当前所有活跃用户，如果用户量多此方法影响性能
     * @return
     */
    @Override
    public Collection<Session> getActiveSessions() {
        //暂时注释，避免程序单个session信息，反序列化异常
        /*List<Session> sessionList = Lists.newArrayList();
        List<byte[]> byteList = Lists.newArrayList();
        //从redis查询
        byteList = RedisUtil.values(ShiroConstant.SHIRO_SESSION_PREFIX);
        for (byte[] bs : byteList){
            sessionList.add((Session) SerializeUtil.deserialize(bs));
        }
        return sessionList;*/
        return null;
    }

    private byte[] getSessionKey(String sessionId){
        return (ShiroConstant.SHIRO_SESSION_PREFIX + sessionId).getBytes();
    }
}
